﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using TTGame;
using System;

/*
 * BulletEffectScript
 *
 *
 *
 * 依赖：
 *
 * ！不写重复代码！
 * @author TTun
 * @date 9/21/2017 9:28:26 AM
 */
namespace TTGameEngine {

[Serializable]
public class EffectTable {
    public static EffectTable Empty = new EffectTable();
    public string bulletTag;
    public string enemyTag;
    public GameObject impactHit;
    public GameObject impactHit2;
    //mark:audio
    public string[] audioNames;
    public bool usePos;
    public string Pos = "Position/Pos_2";
    public float effectcd = 0;
    public bool blockDefaultSound;
    public bool blockDefaultEffect;
}
public class BulletEffectScript : MonoBehaviour {
    public static string PrefabPath = "default/PVE/Prefabs/Game/BulletHitEffects";

    public EffectTable[] bulletToEnemy; //子弹特效
    static BulletEffectScript m_instance;
    public static bool EnableEffect = true;
    public static BulletEffectScript Ins {
        get {
            if(m_instance == null) {
                m_instance = (Instantiate(GameObjectLoader.Ins.GetPrefabObj(BulletEffectScript.PrefabPath)) as GameObject).GetComponent<BulletEffectScript>();
            }
            return m_instance;
        }
    }

    private Dictionary<string, Dictionary<string, EffectTable>> bulletTable;
    void Awake() {
        m_instance = this;
        bulletTable = new Dictionary<string, Dictionary<string, EffectTable>>();
        for(int i = 0; i < bulletToEnemy.Length; i++) {
            EffectTable t = bulletToEnemy[i];
            if(string.IsNullOrEmpty(t.bulletTag)) {
                t.bulletTag = "Untagged";
            }
            if(string.IsNullOrEmpty(t.enemyTag)) {
                t.enemyTag = "Untagged";
            }
            if(!bulletTable.ContainsKey(t.bulletTag)) {
                bulletTable.Add(t.bulletTag, new Dictionary<string, EffectTable>());
            }
            Dictionary<string, EffectTable> ememyTable = bulletTable[t.bulletTag];
            if(!ememyTable.ContainsKey(t.enemyTag)) {
                ememyTable.Add(t.enemyTag, t);
            } else {
                ememyTable[t.enemyTag] = t;
            }
        }
    }
    void OnDestroy() {
        if(m_instance == this) m_instance = null;
    }
    public EffectTable GetEffectByTag(string bulletTag, string enemyTag) {
        if(bulletTable.ContainsKey(bulletTag) && bulletTable[bulletTag].ContainsKey(enemyTag)) {

            return bulletTable[bulletTag][enemyTag];
        }

        return EffectTable.Empty;
    }

    /// <summary>
    /// 预先实例化放入对象回收。实例数量可参考出战人数。
    /// </summary>
    /// <param name="maxCount"></param>
    /// <param name="strategy"></param>
    public void PreInstantiate(int maxCount, RecycleStrategy strategy) {
        Dictionary<GameObject, bool> needInsPrefab = new Dictionary<GameObject, bool>();
        for(int i = 0; i < bulletToEnemy.Length; i++) {
            EffectTable info = bulletToEnemy[i];
            if(info.impactHit != null && needInsPrefab.ContainsKey(info.impactHit) == false) {
                needInsPrefab.Add(info.impactHit, true);
            }
            if(info.impactHit2 != null && needInsPrefab.ContainsKey(info.impactHit2) == false) {
                needInsPrefab.Add(info.impactHit2, true);
            }
        }

        for(var ite = needInsPrefab.GetEnumerator(); ite.MoveNext();) {
            GameObject prefab = ite.Current.Key;
            ObjectRecycler.Instance.PreInstantiateObject(prefab, maxCount, strategy);
        }
    }

    public EffectTable PlayEffect(string bulletTag, Vector3 hitPoint, Puppet hitObj, int LayerID = 0) {
        if(EnableEffect == false) {
            return null;
        }
        EffectTable effect = GetEffectByTag(bulletTag, hitObj.tag);

        if(effect.effectcd > 0 && hitObj != null) {
            if(Time.time - hitObj.BulletEffectCD > effect.effectcd) {
                hitObj.BulletEffectCD = Time.time;
            } else {
                return null;
            }
        }
        if(effect.usePos && !string.IsNullOrEmpty(effect.Pos)) {
            Transform tf = hitObj.GetPosTF(effect.Pos);
            if(tf) {
                hitPoint = tf.position;
            }
        }
#if UNITY_EDITOR
        if(effect.impactHit && effect.impactHit.GetComponentSafe<ObjRecycleTimer>() == null) {
            DebugUtil.LogErrorFormat("策划注意：特效[{0}]应当添加ObjRecycleTimer脚本，用于标记特效何时删除。该特效是填在Prefab[BulletHitEffects]（即，子弹碰撞特效）中", effect.impactHit);
        }
        if(effect.impactHit2 && effect.impactHit2.GetComponentSafe<ObjRecycleTimer>() == null) {
            DebugUtil.LogErrorFormat("策划注意：特效[{0}]应当添加ObjRecycleTimer脚本，用于标记特效何时删除。该特效是填在Prefab[BulletHitEffects]（即，子弹碰撞特效）中", effect.impactHit2);
        }
#endif
        //特效1
        if(effect.impactHit) {
            GameObject go = ObjectRecycler.Instance.InstantiatePrefab(effect.impactHit, hitPoint, Quaternion.identity);
            go.SetLayerInChildren(LayerID);
            //go.transform.LookAt(hitObj.transform);
        }
        //特效2
        if(effect.impactHit2) {
            GameObject go = ObjectRecycler.Instance.InstantiatePrefab(effect.impactHit2, hitPoint, Quaternion.identity);
            go.SetLayerInChildren(LayerID);
            //go.transform.LookAt(hitObj.transform);
        }

        AudioExtensions.PlayClipRandom(effect.audioNames, hitPoint);

        return effect;
    }
}

}
